package org.andengine.shmup;

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Random;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import org.andengine.bulletml.simple.BossData;
import org.simpleframework.xml.*;
import org.simpleframework.xml.core.Persister;

import team2.game.crow.Laser;
import team2.game.crow.SpritePool;

import android.content.res.Resources.NotFoundException;

public class ShooterActivity extends BaseGameActivity implements IOnSceneTouchListener {
    /** Called when the activity is first created. */
	private Serializer s = new Persister();

	private static final int CAMERA_WIDTH = 480;
    private static final int CAMERA_HEIGHT = 720;
    private static final int ACTIVE_SIZE = 5;

    private static final int LAYER_COUNT = 3;
    
    private static final int LAYER_BACKGROUND = 0;
    private static final int LAYER_FOREGROUND = LAYER_BACKGROUND + 1;
    private static final int LAYER_UI = LAYER_FOREGROUND + 1;
    // ===========================================================
    // Fields
    // ===========================================================

    private Camera mCamera;
	private TiledTextureRegion mBlader, mGrunt, mFinalLaser;
	private TiledTextureRegion mFirstBoss;
	private TextureRegion mBullet;
	private Level lev = new Level();
	private BossData d;
	private Boss first;
	private EnemyWave[] waves = new EnemyWave[ACTIVE_SIZE];
	private EnemyPool ep_grunt, ep_blader;
	private int wave_counter = 0;
	private BitmapTextureAtlas mBitmapTextureAtlas, mBTA2;
	private Texture mTexture;
	private Random rng = new Random();

	private Scene scene;

	private BitmapTextureAtlas backgroundTexture;

	private TextureRegion background;

	private TiledTextureRegion mSecondBoss;

	private TiledTextureRegion mSecondBossCore;

	private Boss second;

	private TiledTextureRegion mThirdBoss;

	private TiledTextureRegion mThirdBossCore;

	private Boss third;

	private TiledTextureRegion mFourthBoss;

	private TiledTextureRegion mFourthBossCore;

	private Boss fourth;

	private BitmapTextureAtlas spriteBox;

	private TextureRegion eLaser;

	private SpritePool enemyLaserPool;

	private ArrayList<Laser> enemyShots;

	private TiledTextureRegion mFifthBoss;

	private TiledTextureRegion mFifthBossCore;

	private Boss fifth;

	private TiledTextureRegion mSixthBoss;

	private Boss sixth;

	private TiledTextureRegion mSixthBossCore;

	private Boss seventh;

	private TiledTextureRegion mSeventhBossCore;

	private TiledTextureRegion mSeventhBoss;

	private TiledTextureRegion mEighthBoss;

	private Boss eighth;

	private TiledTextureRegion mEighthBossCore;

	private TiledTextureRegion mNinthBoss;

	private Boss ninth;

    // ===========================================================
    // Constructors
    // ===========================================================

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================

    @Override
    public Engine onLoadEngine() {
            this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);//new Camera(-(CAMERA_WIDTH+60)/2, -(CAMERA_HEIGHT+60)/2, (CAMERA_WIDTH+60)/2, (CAMERA_HEIGHT+60)/2);
            final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), mCamera);
    		engineOptions.getTouchOptions().setRunOnUpdateThread(true);
    		//mCamera.setCenter(0, 0);
            return new Engine(engineOptions);
    }

    @Override
    public void onLoadResources() {
    	
    	this.mBitmapTextureAtlas = new BitmapTextureAtlas(2048, 2048, TextureOptions.BILINEAR);
    	/*
    	this.mGrunt = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "Grunt.png",0,0, 3, 2);
    	this.mBlader = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "Blader.png",0,108, 6, 1);
    	this.mFirstBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FirstBoss.png", 0, 219, 1,1);
    	this.mBullet = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "EnemyLaser.png", 0, 399);
    	this.mFinalLaser = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FinalLaser.png", 480, 0, 3,1);
    	this.mSecondBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "BossTwo.png", 753, 0, 1,1);
    	this.mSecondBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "SecondBossCore.png", 1553, 0, 4,1);
    	*/
    	/*
    	this.mThirdBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "ThirdBoss.png", 0, 410, 1,1);
    	this.mThirdBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "ThirdBossCore.png", 0, 1010, 3,2);
    	//*/
    	this.spriteBox = new BitmapTextureAtlas(1024,1024);
		
    	this.mBullet = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "EnemyLaser.png", 0, 399);
    	this.mFinalLaser = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FinalLaser.png", 480, 0, 3,1);
    	//this.mFourthBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FourthBoss.png", 1024, 1024, 2,1);
    	//this.mFourthBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FourthBossCore.png", 1553, 0, 3,1);
    	//this.mFifthBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FifthBoss.png", 1024, 1024, 1,1);
    	//this.mFifthBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "FifthBossCore.png", 1427, 0, 3,1);
    	//this.mSixthBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "SixthBoss.png", 1024, 1024, 1,1);
    	//this.mSixthBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "SixthBossCore.png", 1427, 0, 4,2);
    	//this.mSeventhBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "SeventhBoss.png", 1024, 1024, 1,1);
    	//this.mSeventhBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "SeventhBossCore.png", 1600, 0, 4,2);
    	//this.mEighthBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "EigthBoss.png", 1024, 1024, 1,1);
    	//this.mEighthBossCore = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "EigthBossCore.png", 1600, 0, 1,1);
    	this.mNinthBoss = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "NinthBoss.png", 1024, 1024, 2,2);
    	
    	this.eLaser = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.spriteBox, this, "EnemyLaser.png",589,12);
		
    	/*
    	this.mGrunt = TextureRegionFactory.createTiledFromAsset(mTexture, this, "Grunt.png", 0, 0, 3, 2);
    	this.mBlader = TextureRegionFactory.createTiledFromAsset(mTexture, this, "Blader.png", 0, 120, 6, 1);
    	this.mEngine.getTextureManager().loadTexture(mTexture);
    	*/
    	//this.ep_grunt = new EnemyPool(mGrunt, CAMERA_WIDTH, CAMERA_HEIGHT);
    	//this.ep_blader = new EnemyPool(mBlader, CAMERA_WIDTH, CAMERA_HEIGHT);

    	this.enemyLaserPool = new SpritePool(eLaser);
    	this.enemyShots = new ArrayList<Laser>();
    	
    	this.backgroundTexture = new BitmapTextureAtlas(1024, 1024, TextureOptions.BILINEAR);
    	this.background = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.backgroundTexture, this, "Background Swirly.png", 0, 0);
    	this.mEngine.getTextureManager().loadTexture(this.backgroundTexture);
    	this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
    	this.mEngine.getTextureManager().loadTexture(this.spriteBox);
	
    }

    @SuppressWarnings("deprecation")
	@Override
    public Scene onLoadScene() {
    	
			this.scene = new Scene(LAYER_COUNT);
            this.mEngine.registerUpdateHandler(new FPSLogger());
    		scene.setOnSceneTouchListener(this);
            
            this.scene.setBackgroundEnabled(false);
    		this.scene.getChild(LAYER_BACKGROUND).attachChild(new Sprite(0, 0, this.background));
    		
    		/************************************************
    		 * This is where the XML file is actually read. *
    		 ************************************************/
    		try{
    		d = s.read(BossData.class, this.getResources().openRawResource(R.raw.boss9));
			Debug.d("XML read!");
			Debug.d(d.toString());
			Debug.d("finished reading...");
			/*
			first = new Boss(0,0, mFirstBoss, d, mFinalLaser);
			first.setBulletPool(enemyLaserPool);
			first.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(first);
			first.init();
			*/
			/*
			second = new Boss(0,0, mSecondBoss, d, mFinalLaser);
			second.setBulletPool(enemyLaserPool);
			second.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(second);
			second.init();
			second.addExternalAnimSprite(204, 204, mSecondBossCore, 80, "core");
			*/
			/*
			third = new Boss(CAMERA_WIDTH/2 - mThirdBoss.getTileWidth()/2,0, mThirdBoss, d, mFinalLaser);
			third.setBulletPool(enemyLaserPool);
			third.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(third);
			third.init();
			third.addExternalAnimSprite(third.getX() + 101, 86, mThirdBossCore, 80, "core");
			//*/
			/*
			fourth = new Boss(CAMERA_WIDTH/2 - mFourthBoss.getTileWidth()/2,0, mFourthBoss, d, mFinalLaser);
			fourth.setBulletPool(enemyLaserPool);
			fourth.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(fourth);
			fourth.init();
			fourth.addExternalAnimSprite(fourth.getX() + 101, 86, mFourthBossCore, 80, "core");
			*/
			/*
			fifth = new Boss(0,60, mFifthBoss, d, mFinalLaser);
			fifth.setBulletPool(enemyLaserPool);
			fifth.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(fifth);
			fifth.init();
			fifth.addExternalAnimSprite(393, 13, mFifthBossCore, 80, "core");
			*/
			/*
			sixth = new Boss(CAMERA_WIDTH/6,0, mSixthBoss, d, mFinalLaser);
			sixth.setBulletPool(enemyLaserPool);
			sixth.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(sixth);
			sixth.init();
			sixth.addExternalAnimSprite(sixth.getX() + sixth.getTextureRegion().getTileWidth()/3 + 10, sixth.getTextureRegion().getTileHeight()/3 + 10, mSixthBossCore, 80, "core");
			*/
			/*
			seventh = new Boss(0,0, mSeventhBoss, d, mFinalLaser);
			seventh.setBulletPool(enemyLaserPool);
			seventh.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(seventh);
			seventh.init();
			seventh.addExternalAnimSprite(195,63, mSeventhBossCore, 80, "core");
			*/
			/*
			eighth = new Boss(0,0, mEighthBoss, d, mFinalLaser);
			eighth.setBulletPool(enemyLaserPool);
			eighth.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(eighth);
			eighth.init();
			eighth.addExternalAnimSprite(185.5f,230.5f, mEighthBossCore, 80, "core");
			*/
			ninth = new Boss(0,0, mNinthBoss, d, mFinalLaser);
			ninth.animate(80);
			ninth.setBulletPool(enemyLaserPool);
			ninth.setBulletArray(enemyShots);
			scene.getChild(LAYER_FOREGROUND).attachChild(ninth);
			ninth.init();
			
		} catch (NotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
			/************************************************/
			
			/*
			 * Stuff to be re-ipmlemented at some point
        	int i = 0;
        	try {
				while(lev.hasNextWave()){
					waves[i] = lev.getNextWave();
					if(waves[i].getEnemyType().equals("GRUNT"))
						waves[i].spawnEnemies(ep_grunt);
					else if(waves[i].getEnemyType().equals("BLADER"))
						waves[i].spawnEnemies(ep_blader);
					i = (i+1)%ACTIVE_SIZE;
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for(int x = 0; x < i; x++){
				for(Enemy e: waves[x].getEnemies()){
					e.animate(100);
					scene.getFirstChild().attachChild(e);
				}
			}
			 */
            return scene;
    }

	@Override
	public void onLoadComplete() {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		Debug.d("(" + pSceneTouchEvent.getX() + ", " + pSceneTouchEvent.getY() + ")");
		return false;
	}
	
	
}